<?php
namespace froyo\cherry\web;

use froyo\cherry\Base\BaseRequest;
use froyo\cherry\Base\Cherry;

class Request extends BaseRequest {
	public $url; //完整url
	public $host; //域名
	public $port; //端口
	public $scheme; //协议
	public $pathinfo; //pathinfo信息
	public $querystr; //query参数
	public $requesturi; //requesturi
	public $queryparams; //查询参数
	public $method; //请求方式
	public $methodParam = '_method'; //表单模拟请求方式
	public $headers = [];
	protected $_baseUrl;
	protected $_scriptFile;
	protected $_scriptUrl;

	public function getHeader($name,$default='')
	{
		if(isset($this->headers[$name]))
		{
			return $this->headers[$name];
		}
		return $default;
	}

	public function getBaseUrl() {
		if ($this->_baseUrl === null) {
			$this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/');
		}

		return $this->_baseUrl;
	}
    public function getScriptFile()
    {
        if (isset($this->_scriptFile)) {
            return $this->_scriptFile;
        }

        if (isset($_SERVER['SCRIPT_FILENAME'])) {
            return $_SERVER['SCRIPT_FILENAME'];
        }

        throw new \Exception('Unable to determine the entry script file path.');
    }
	public function getScriptUrl() {
		if ($this->_scriptUrl === null) {
			$scriptFile = $this->getScriptFile();
			$scriptName = basename($scriptFile);
			if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $scriptName) {
				$this->_scriptUrl = $_SERVER['SCRIPT_NAME'];
			} elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $scriptName) {
				$this->_scriptUrl = $_SERVER['PHP_SELF'];
			} elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $scriptName) {
				$this->_scriptUrl = $_SERVER['ORIG_SCRIPT_NAME'];
			} elseif (isset($_SERVER['PHP_SELF']) && ($pos = strpos($_SERVER['PHP_SELF'], '/' . $scriptName)) !== false) {
				$this->_scriptUrl = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $scriptName;
			} elseif (!empty($_SERVER['DOCUMENT_ROOT']) && strpos($scriptFile, $_SERVER['DOCUMENT_ROOT']) === 0) {
				$this->_scriptUrl = str_replace([$_SERVER['DOCUMENT_ROOT'], '\\'], ['', '/'], $scriptFile);
			} else {
				throw new \Exception('Unable to determine the entry script URL.');
			}
		}

		return $this->_scriptUrl;
	}
	public function getPathInfo() {
		$pathInfo = $this->getRequesturi();

		if (($pos = strpos($pathInfo, '?')) !== false) {
			$pathInfo = substr($pathInfo, 0, $pos);
		}

		$pathInfo = urldecode($pathInfo);

		$scriptUrl = $this->getScriptUrl();
		$baseUrl = $this->getBaseUrl();

		if (strpos($pathInfo, $scriptUrl) === 0) {
			$pathInfo = substr($pathInfo, strlen($scriptUrl));
		} elseif ($baseUrl === '' || strpos($pathInfo, $baseUrl) === 0) {
			$pathInfo = substr($pathInfo, strlen($baseUrl));
		} elseif (isset($_SERVER['PHP_SELF']) && strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) {
			$pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl));
		} else {
			throw new \Exception('Unable to determine the path info of the current request.');
		}

		if (substr($pathInfo, 0, 1) === '/') {
			$pathInfo = substr($pathInfo, 1);
		}

		return (string) $pathInfo;
	}

	public function getMethod() {
		if (!$this->method) {
			if (isset($_POST[$this->methodParam])) {
				$this->method = strtoupper($_POST[$this->methodParam]);
			} elseif ($this->getHeader('X-Http-Method-Override')) {
				$this->method = strtoupper($this->getHeader('X-Http-Method-Override'));
			} elseif ($_SERVER['REQUEST_METHOD']) {
				$this->method = strtoupper($_SERVER['REQUEST_METHOD']);
			} else {
				$this->method = 'GET';
			}
		}

		return $this->method;

	}

	public function getScheme() {
		if (!$this->scheme) {
			$this->scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? "https" : "http";
		}
		return $this->scheme;
	}

	public function getHost() {
		if (!$this->host) {
			$this->host = $_SERVER['HTTP_HOST'];
		}
		return $this->host;
	}

	public function getRequesturi() {
		if (!$this->requesturi) {


	        if ($this->getHeader('X-Rewrite-Url')) { // IIS
	            $requestUri = $this->getHeader('X-Rewrite-Url');
	        } elseif (isset($_SERVER['REQUEST_URI'])) {
	            $requestUri = $_SERVER['REQUEST_URI'];
	            if ($requestUri !== '' && $requestUri[0] !== '/') {
	                $requestUri = preg_replace('/^(http|https):\/\/[^\/]+/i', '', $requestUri);
	            }
	        } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0 CGI
	            $requestUri = $_SERVER['ORIG_PATH_INFO'];
	            if (!empty($_SERVER['QUERY_STRING'])) {
	                $requestUri .= '?' . $_SERVER['QUERY_STRING'];
	            }
	        } else {
	            throw new \Exception('Unable to determine the request URI.');
	        }

	        $this->requesturi = $requestUri;


		}
		return $this->requesturi;
	}
	public function getQueryparams() {
		if ($this->queryparams === null) {
			$this->queryparams = $_GET;
		}
		return $this->queryparams;
	}

	public function get($name, $default = '') {
		$queryparams = $this->getQueryparams();
		if (isset($queryparams[$name])) {
			return $queryparams[$name];
		}
		return $default;
	}

	public function getUrl() {
		if (!$this->url) {
			$this->url = $this->getScheme() . "://" . $this->getHost() . $this->getRequesturi();
		}
		return $this->url;
	}

	public function resolve() {
		return Cherry::$app->getRoute()->paraseRequest($this);
	}
}